<template>
  <div class="video-watermark-container">
    <div class="input-section">
      <div class="button-container">
        <button @click="chooseFile">上传视频文件</button>
        <button @click="removeWatermark" class="remove-watermark-btn">
          去除水印
        </button>
        <button @click="clearRect" class="clear-btn">
          清除框
        </button>
        <button @click="downloadVideo" class="download-btn">
          下载视频
        </button>
      </div>
    </div>
    <div class="video-section" style="position: relative; width: 800px; height: 450px;">
      <canvas id="video-canvas" ref="canvasRef" style="position: absolute; top: 0; left: 0; z-index: 1;"></canvas>
      <video id="video" ref="videoRef" :src="videoUrl" controls class="video-player" @click="drawRect"
             style="position: absolute; top: 0; left: 0; z-index: 0; width: 800px; height: 450px;"></video>
      <video :src="noWaterVideoUrl" ref="noWaterVideoRef" controls class="video-player" @click="drawRect"
             v-show="noWaterVideoUrl"
             style="position: absolute; top: 460px; left: 0; z-index: 0; width: 800px; height: 450px;"></video>
    </div>
  </div>
</template>


<script lang="ts" setup>
import {ref, reactive, toRefs, onMounted} from 'vue';
import {postVideoRemoveWatermark} from '@/js/api/video';
import {UIUtils} from '@/js/utils/uiUtils';

const state = reactive({
  videoUrl: 'https://tczlld.com/oss/douyin.mp4',
  noWaterVideoUrl: '',
  videoSize: {
    width: 0,
    height: 0
  },


  fileId: '',
  scale: 1,
  isDrawing: false,
  rect: {
    x: 0,
    y: 0,
    width: 0,
    height: 0
  },
})

const {videoUrl, noWaterVideoUrl, videoSize, fileId, scale, isDrawing, rect} = toRefs(state)

onMounted(() => {
  const videoElement = document.getElementById('video');
  videoElement.addEventListener('loadedmetadata', initCanvas);
})

var canvasRef = ref()


var ctx: CanvasRenderingContext2D;


const chooseFile = () => {
  const input = document.createElement('input');
  input.type = 'file';
  input.accept = 'video/*';
  input.onchange = (event) => {
    const file = event.target.files[0];
    if (file) {
      uploadFile(file);
    }
  };
  input.click();
}

const uploadFile = (file) => {
  const formData = new FormData();
  formData.append('file', file);

  fetch('http://localhost/openai/oss/files', {
    method: 'POST',
    body: formData
  })
      .then(response => response.json())
      .then(data => {
        if (data.code === 200) {
          UIUtils.showToast('文件上传成功！', 'success');
          videoUrl.value = data.data.url;
          fileId.value = data.data.fileId;
        } else {
          UIUtils.showToast('文件上传失败。', 'error');
        }
      })
      .catch(error => {
        console.error('上传文件时发生错误:', error);
        UIUtils.showToast('上传过程中发生错误。', 'error');
      });
}

const downloadVideo = async () => {
  if (!noWaterVideoUrl) {
    UIUtils.showToast('请先去除视频水印', 'error');
    return;
  }

  UIUtils.showLoading('正在下载视频...');
  const a = document.createElement('a');
  a.href = noWaterVideoUrl.value;
  a.download = 'video.mp4';
  a.click();
  a.remove();
  UIUtils.hideLoading();
  UIUtils.showToast('下载完成', 'success');
}


const initCanvas = (event) => {

  const videoElement = event.target;
  videoSize.value.width = videoElement.videoWidth;
  videoSize.value.height = videoElement.videoHeight;
  console.log("videoSize", videoSize.value)
  console.log("canvasRef", canvasRef.value)

  if (canvasRef.value && canvasRef.value instanceof HTMLCanvasElement) {
    console.log("canvasRef", canvasRef.value)
    ctx = canvasRef.value.getContext('2d')
  } else {
    console.error('Failed to obtain a valid canvas element.');
    return;
  }

  canvasRef.value.width = videoSize.value.width;
  canvasRef.value.height = videoSize.value.height



  const videoOffsetWidth = videoElement.offsetWidth
  const videoOffsetHeight = videoElement.offsetHeight




  console.log("videoElement", videoOffsetWidth)
  console.log("videoElement", videoOffsetHeight)

  const aspectRatio = videoSize.value.width / videoSize.value.height;
  const videoAspectRatio = videoOffsetWidth / videoOffsetHeight;


  console.log("aspectRatio", aspectRatio)
  console.log("videoAspectRatio", videoAspectRatio)
  if (aspectRatio < videoAspectRatio) {

    // 说明视频的高度比较小
    scale.value = videoOffsetHeight / videoSize.value.height;

    const videoWidth = videoSize.value.width * scale.value;
    const videoHeight = videoSize.value.height * scale.value;
    const videoX = (videoOffsetWidth - videoWidth) / 2;
    console.log("videoX", videoX)

    const videoY = 0;

    canvasRef.value.style.width = videoWidth + 'px';
    canvasRef.value.style.height = videoHeight + 'px';
    canvasRef.value.style.left = videoX + 'px';
    canvasRef.value.style.top = videoY + 'px';
    canvasRef.value.style.border = '1px solid red'; // 便于调试 canvas 位置

  } else {

    scale.value = videoOffsetWidth / videoSize.value.width;
    const videoWidth = videoSize.value.width * scale.value;
    const videoHeight = videoSize.value.height * scale.value;
    const videoX = 0;
    const videoY = (videoOffsetHeight - videoHeight) / 2;

    canvasRef.value.style.width = videoWidth + 'px';
    canvasRef.value.style.height = videoHeight + 'px';
    canvasRef.value.style.left = videoX + 'px';
    canvasRef.value.style.top = videoY + 'px';
    canvasRef.value.style.border = '1px solid red'; // 便于调试 canvas 位置


  }
  console.log("scale", scale)

  canvasRef.value.addEventListener('mousedown', startDrawing.bind(this));
  canvasRef.value.addEventListener('mousemove', draw.bind(this));
  canvasRef.value.addEventListener('mouseup', stopDrawing.bind(this));
}


const startDrawing = (e) => {
  console.log("start drawing")
  isDrawing.value = true;
  console.log("e.offsetX=" + e.offsetX + ",e.offsetY=" + e.offsetY)
  rect.value.x = e.offsetX; // 使用 offsetX 和 offsetY
  rect.value.y = e.offsetY;
  console.log("rect.x=" + rect.value.x + ",rect.y=" + rect.value.y)

}
const draw = (e) => {
  if (isDrawing.value) {
    rect.value.width = e.offsetX - rect.value.x;
    rect.value.height = e.offsetY - rect.value.y;
    console.log("rect.width=" + rect.value.width + ",rect.height=" + rect.value.height)
    drawRect();
  }
}

const stopDrawing = () => {
  isDrawing.value = false;
}

const drawRect = () => {
  console.log("Drawing rectangle");

  const newData = {
    x: Math.max(rect.value.x / scale.value, 0),
    y: Math.max(rect.value.y / scale.value, 0),
    width: rect.value.width / scale.value,
    height: rect.value.height / scale.value
  };
  ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height);
  ctx.strokeStyle = 'red';
  ctx.lineWidth = 2;

  ctx.strokeRect(newData.x, newData.y, newData.width, newData.height);


  console.log("newData", newData)
}


const clearRect =async () => {
  if (canvasRef.value && ctx) {
    ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height);
    rect.value = {
      x: 0,
      y: 0,
      width: 0,
      height: 0
    };
  }
}
const removeWatermark = async () => {
  if (!videoUrl) {
    UIUtils.showToast('请先上传视频', 'error');
    return;
  }

  if (rect.value.width === 0 || rect.value.height === 0) {
    UIUtils.showToast('请先框选水印区域', 'error');
    return;
  }

  try {
    UIUtils.showLoading('正在去除水印...');
    const data = {
      fileId: fileId.value,
      x: Math.max(rect.value.x / scale.value, 0),
      y: Math.max(rect.value.y / scale.value, 0),
      width: rect.value.width / scale.value,
      height: rect.value.height / scale.value
    };
    const response = await postVideoRemoveWatermark(data);

    UIUtils.hideLoading();

    if (response.code === 200 && response.data) {
      noWaterVideoUrl.value = response.data.url;
      UIUtils.showToast('去除水印成功', 'success');
    } else {
      UIUtils.showToast('去除水印失败，请检查参数是否正确', 'error');
    }
  } catch (error) {
    UIUtils.hideLoading();
    console.error('去除水印出错:', error);
    UIUtils.showToast('去除水印出错，请稍后重试', 'error');
  }
}
</script>


<style scoped>
.input-section {
  margin-bottom: 20px;
}

.button-container {
  display: flex;
  gap: 5px;
  /* 按钮之间的间距调整为5像素 */
}

.upload-btn,
.remove-watermark-btn,
.clear-btn {
  padding: 8px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.upload-btn {
  background-color: #67c23a;
  color: white;
}

.remove-watermark-btn {
  background-color: #e6a23c;
  color: white;
}

.clear-btn {
  background-color: #909399;
  color: white;
}
</style>
